[アップデート] システムのリファクタリングを後押しするプロキシ層を提供「AWS Migration Hub Refactor Spaces」がプレビューリリースされました #reinvent
re:Invent期間中に発表された新サービス「AWS Migration Hub Refactor Spaces」について紹介します。
AWS Migration Hub Refactor Spacesは現在パブリックプレビューですので、どなたでもお試しいただけます。また、本記事の内容はパブリックプレビュー版をもとに執筆していますので、将来的に仕様が変更される可能性がある点はご注意ください。
AWS Migration Hub Refactor Spaces
Strangler Fig パターン
古いシステムをリファクタリングしたいと思いながらも、まとまった時間、お金、リソースも確保が厳しいなぁ。一気にリプレースするのはやっぱリスクがあるよね。ベストではないけど何とか使えてるし、しばらくこのままで、、、リファクタリングが進められない悩みは多くのユーザーが抱えていることかと思います。
一方で少ない成功事例に共通したモデルとして紹介されているのが「Strangler Fig」というパターンです。
Strangler Fig は和訳すると「絞め殺しの木」となんともおぞましい名前が付けられていますが、公式ブログでより拝借いたしました以下写真のように宿主となる木を覆うように根を這わせ、最終的に宿主の木を包み込んで置き換わってしまう植物とのことです。
(引用元:Preview – AWS Migration Hub Refactor Spaces Helps to Incrementally Refactor Your Applications)
古いシステムは一気にリファクタリングするのではなく、周辺システムから徐々に新しいシステムへと作り変え、最終的に古いシステムが「絞め殺される」まで数年かけてゆっくりとリファクタリングしていくことから「Strangler Fig」と名付けられたようです。
AWS Migration Hub Refactor Spaces はプロキシだ!
こちらも公式ブログの画像引用ですが、例えばフロントはCloudFront+S3で提供されおり、APIのエンドポイントはレガシーなEC2/RDSのシステムで実装されています。
(引用元:Preview – AWS Migration Hub Refactor Spaces Helps to Incrementally Refactor Your Applications)
ここから/cart
機能の一部のみをマイクロサービスとしてLambdaに切り出すとした場合、既存アプリケーションと新しいサービスをつなぐネットワークを整備する必要がある、という課題に直面します。また各マイクロサービス毎に権限管理、コスト管理を容易にするためにAWSアカウントを分離することも珍しくありませんので、マルチアカウントでトラフィックのルーティング制御も必要になります。
(引用元:Preview – AWS Migration Hub Refactor Spaces Helps to Incrementally Refactor Your Applications)
そこでリリースされたのが「AWS Migration Hub Refactor Spaces」です。ちなみにAWS Migration Hubという名前がついていますが、今のところ従来のAWS Migration Hubとの関連性はあまり無いように思います。
AWS Migration Hub Refactor Spacesはこの複雑なトラフィックのルーティングをAmazon API Gateway、Network Load Balancer、AWS Transit Gateway、AWS Resource Access Managerなどの既存サービスを駆使し、ユーザーにこれらのリソースを意識させることなくプロキシ層を提供するサービスです。
(引用元:Preview – AWS Migration Hub Refactor Spaces Helps to Incrementally Refactor Your Applications)
AWSインフラ構築に携わっている人であれば、これらのリソースを使ってマルチアカウントのトラフィック制御することがどれだけ複雑で面倒な作業であるか想像するのは難しくないと思いますが、開発者はAWS Migration Hub Refactor Spaceの管理画面から作成できたアプリケーション部分のみ、例えば/cart
をLambda関数や新たなVPCリソースに向けるように設定するだけで、裏でAPI Gatewayのメソッド定義が行われてデプロイされたり、Transit GatewayのVPC関連付けやルーティング設定が行われます。
フロントエンドアプリは従来のエンドポイントをAWS Migration Hub Refactor Spacesでデプロイされたプロキシ用のAPI GatewayのエンドポイントURLに一度切り替えてしまえば、あとはプロキシ内のトラフィック制御によってリリースされた新しいサービスへと切り替わっていきます。
リージョン
以下の10リージョンで既に利用かのうです
- バージニア
- オレゴン
- オハイオ
- シンガポール
- シドニー
- 東京
- アイルランド
- フランクフルト
- ロンドン
- ストックホルム
(つд⊂)ゴシゴシ(゚Д゚)オオサカ ナインヤケド?
料金
現在はプレビュー中のためAWS Migration Hub Refactor Spacesに対する課金は発生しません。ただし、AWS Migration Hub Refactor Spacesで作成される各種既存サービスには料金が発生しますのでご注意ください。
プレビュー期間終了後は、以下の料金が発生します。
Environments
- 1環境あたり 0.028 USD/時間
APIリクエスト
- 0.000002ドル/リクエスト(1.00 USD/100マンリクエスト)
やってみた
今回は東京リージョンで検証しています。
AWS Migration Hub Refactor Spacesでは「AWS Migration Hub Refactor Spaces管理者用」「既存サービス用」「新サービス用」のように3アカウントに分けることを推奨されていますが、今回は検証環境の都合上「AWS Migration Hub Refactor Spaces管理者用」「既存サービス/新サービス」の2アカウントで検証としました。
事前に既存サービスとしてEC2で雑なAPIエンドポイントを作成済みです。
$ curl -X GET http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/hoge [GET]/hoge on EC2 $ curl -X POST http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/hoge [POST]/hoge on EC2 $ curl -X GET http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/fuga [GET]/fuga on EC2 $ curl -X POST http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/fuga [POST]/fuga on EC2
最終的にGET /hoge
のみをLambda関数に移行することを想定して進めます。
EnvironmentおよびApplicationの作成
Migration Hubの管理コンソールを開き[Refactor Spaces]-[App Refactor]-[Enviromnets]-[Create Enviromnent]をクリックします。任意のEnvironment nameを入力し[Next]へ。
EnvironmentはVPCで構成されるマルチアカウントのネットワークファブリックになります。Environmentの作成によって内部的にはTransit Gatewayが作成されています。
任意のApplication Nameを入力。Proxyとして利用するVPCを選択します。Proxy endpoint typeはパブリックから接続する環境であればRegional、VPC内からのみであればPrivateを選択します。
Applicationの設定によって指定したVPCにNetwork Load Balancerが設置され、Proxy endpoint typeの設定はそのままAPI Gatewayのエンドポイントタイプになります。
このEnvironmentを共有する他のアカウントを招待します。Organization、Oranization unit(OU)だけでなくAWSアカウントを指定してOrganization外部のアカウントを招待することも出来ます。今回はAWSアカウント指定でOrganization外部のアカウントで検証しています。
この設定によりEnvironmentおよびTransitGatewayがAWS Resource Access Managerによって他のアカウントと共有可能になります。
設定値を確認して[Create & share environment]をクリック
EnvironmentおよびApplicationの作成が完了すると、Transit GatewayおよびAPI Gatewayが自動的に作成されていることが解ります。
Applicationの詳細を確認すると指定したProxy VPC内にNetwork Load Balancerも自動的に作成されていることも確認できました。
共有設定の承認
先ほどリソース共有で指定したアカウントに切り替え、Refactor Spacesの管理画面を開くと以下のように共有設定の承認通知が届いていますので[Accept share]で承認します。
Serviceの作成
既存サービス提供側のAWSアカウントに切り替え、Refactor Spacesの管理画面から[Quick actions]-[Create service]を開きます。先ほど作成したEnvironmentおよびApplicationを選択し、任意のService nameを入力します。
既存サービスで提供しているVPCを選択し、エンドポイントURLを入力します。ヘルスチェックパスが異なる場合は特定のヘルスチェックパスを設定します。Set this service as the applications's default route.
にチェックを入れると、このアプリケーションが特定のパスパターンにマッチしない場合のデフォルトとしてリクエストを受けます。
なお、AWS Resource Access ManagerでTransit GatewayをEnvironment内で共有していますので、異なるアカウントであってもVPC CIDR重複は許されないようですのでお気をつけください。
Serviceの登録が完了し、Routeのヘルスチェックが正常に確認されるとProxyのエンドポイントURLが有効になります。フロントエンドサービスからはこのエンドポイントURLに対してリクエストするように切り替えを行ってください。
Routeのヘルスチェックが確認されると裏ではAPI Gatewayのメソッドの作成やデプロイが自動的に行われています。
またTransit Gatewayの関連付けやルート設定も自動的に行われています。
既存サービスへのリクエストの確認
パブリックな環境からProxyエンドポイントに対してリクエストを行っています。この時点ではすべてEC2にリクエストが流れていることが確認できました。
$ curl -X GET https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/hoge [GET]/hoge on EC2 $ curl -X POST https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/hoge [POST]/hoge on EC2 $ curl -X GET https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/fuga [GET]/fuga on EC2 $ curl -X POST https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/fuga [POST]/fuga on EC2
GET /hoge のみ Lambda に変更
新サービス提供側のAWSアカウントに切り替え、Refactor Spacesの管理画面から[Quick actions]-[Create service]を開きます。先ほど作成したEnvironmentおよびApplicationを選択し、任意のService nameを入力します。
Lambda
を選択し、リクエスト先のLambda関数を指定します。今回はGET /hoge
のみを対象に指定しました。
登録が完了すると以下のようになります。
API Gatewayを確認すると/hoge
に対するリソースパスが作成されて自動的にデプロイされています。
/hoge
のリソースパスが作成されたことで、これまでCatch-allの/{proxy+}
に流れていたPOST /hoge
などGET以外のリクエストはANY /hoge
にリクエストが流れることになります。しかしながらANY /hoge
のエンドポイントURLはデフォルトのままですので、このままでは期待した動作をしません。
/{proxy+}: x-amazon-apigateway-any-method: parameters: - name: "proxy" in: "path" required: true schema: type: "string" x-amazon-apigateway-integration: httpMethod: "ANY" uri: "http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/{proxy}"
GET /hoge
のみLambdaに向けた状態だと以下のようになります。
/hoge: x-amazon-apigateway-any-method: parameters: - name: "proxy" in: "path" required: true schema: type: "string" x-amazon-apigateway-integration: httpMethod: "ANY" uri: "http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000"
上記のままリクエストすると以下のように405
エラーになります
$ curl -X POST https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/hoge/ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>405 Method Not Allowed</title> <h1>Method Not Allowed</h1> <p>The method is not allowed for the requested URL.</p>
ANY /hoge のサービスを追加
これを回避するためには明示的にANY /hoge
のエンドポイントURLをhttp://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/hoge
として登録する必要があります。
設定は以上で完了です。
動作確認
期待したとおりGET /hoge
のみLambdaに切り替わったことが確認できました。
$ curl -X GET https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/hoge "Hello from Lambda!" $ curl -X POST https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/hoge [POST]/hoge on EC2 $ curl -X GET https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/fuga [GET]/fuga on EC2 $ curl -X POST https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/fuga [POST]/fuga on EC2
検証は以上です!
私はインフラ屋なのでRefactor Spacesの各設定に対して対向となるサービスの設定画面を逐次確認していますが、基本的にRefactor Spacesで設定するだけで開発者はAPI GatewayやTransit Gatewayなどの設定画面を操作することなくマルチアカウントのトラフィック制御ができると思います。すごい!
まとめ
- 古いシステムのリファクタリングは周辺から徐々に置き換えていく「Strangler Fig」パターンが成功事例の共通点
- 徐々にリファクタリングするには複雑なトラフィックを制御するプロキシが必要
- AWS Migration Hub Refactor Spacesはそのプロキシを以下のサービスをラップして作成、設定してくれる
- API Gateway
- Network Load Balancer
- Transit Gateway
- RAM
- 開発者はRefactor Spacesの管理画面から切り替えるパスとターゲットを登録するだけで、自動的にこれらのサービスの設定、デプロイが行われる